/// 计价系统通用工具函数
use std::collections::HashMap;

// ================================
// 数值计算工具
// ================================

/// 安全的浮点数乘法，防止溢出
pub fn safe_multiply(
    a: f64,
    b: f64,
) -> Result<f64, crate::CommonCalculationError> {
    let result = a * b;
    if result.is_infinite() || result.is_nan() {
        return Err(crate::CommonCalculationError::CalculationOverflow(format!("{} * {} = {}", a, b, result)));
    }
    Ok(result)
}

/// 安全的百分比计算
pub fn calculate_percentage(
    base: f64,
    rate: f64,
) -> Result<f64, crate::CommonCalculationError> {
    if base < 0.0 {
        return Err(crate::CommonCalculationError::InvalidParameter { field: "base".to_string(), value: base.to_string() });
    }

    if rate < 0.0 || rate > 100.0 {
        return Err(crate::CommonCalculationError::InvalidParameter { field: "rate".to_string(), value: rate.to_string() });
    }

    safe_multiply(base, rate / 100.0)
}

/// 应用调整系数
pub fn apply_adjustment_factor(
    base_value: f64,
    factor: f64,
) -> Result<f64, crate::CommonCalculationError> {
    if factor < 0.0 {
        return Err(crate::CommonCalculationError::InvalidParameter { field: "adjustment_factor".to_string(), value: factor.to_string() });
    }

    safe_multiply(base_value, factor)
}

// ================================
// 地区代码工具
// ================================

/// 验证地区代码格式
pub fn validate_region_code(region_code: &str) -> Result<(), crate::CommonConfigError> {
    if region_code.is_empty() {
        return Err(crate::CommonConfigError::MissingRequired("region_code".to_string()));
    }

    if region_code.len() != 6 {
        return Err(crate::CommonConfigError::InvalidValue { key: "region_code".to_string(), value: region_code.to_string() });
    }

    if !region_code.chars().all(|c| c.is_ascii_digit()) {
        return Err(crate::CommonConfigError::InvalidValue { key: "region_code".to_string(), value: region_code.to_string() });
    }

    Ok(())
}

/// 从地区代码获取省份代码
pub fn get_province_code(region_code: &str) -> Result<String, crate::CommonConfigError> {
    validate_region_code(region_code)?;
    Ok(region_code[0..2].to_string() + "0000")
}

/// 从地区代码获取城市代码
pub fn get_city_code(region_code: &str) -> Result<String, crate::CommonConfigError> {
    validate_region_code(region_code)?;
    Ok(region_code[0..4].to_string() + "00")
}

// ================================
// 配置合并工具
// ================================

/// 合并HashMap配置，右边覆盖左边
pub fn merge_config_maps<K, V>(
    left: HashMap<K, V>,
    right: HashMap<K, V>,
) -> HashMap<K, V>
where
    K: Eq + std::hash::Hash + Clone,
    V: Clone,
{
    let mut result = left;
    for (key, value) in right {
        result.insert(key, value);
    }
    result
}

/// 深度合并配置，支持嵌套
pub fn deep_merge_adjustment_factors(
    base: &HashMap<String, f64>,
    override_map: &HashMap<String, f64>,
) -> HashMap<String, f64> {
    let mut result = base.clone();

    for (key, value) in override_map {
        result.insert(key.clone(), *value);
    }

    result
}

// ================================
// 验证工具
// ================================

/// 验证费率范围
pub fn validate_rate_range(
    rate: f64,
    min: f64,
    max: f64,
    field_name: &str,
) -> Result<(), crate::CommonCalculationError> {
    if rate < min || rate > max {
        return Err(crate::CommonCalculationError::InvalidParameter {
            field: field_name.to_string(),
            value: format!("{} (范围: {}-{})", rate, min, max),
        });
    }
    Ok(())
}

/// 验证必需字段
pub fn validate_required_field<T>(
    field: &Option<T>,
    field_name: &str,
) -> Result<(), crate::CommonCalculationError> {
    if field.is_none() {
        return Err(crate::CommonCalculationError::MissingField(field_name.to_string()));
    }
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_safe_multiply() {
        assert!(safe_multiply(100.0, 0.15).is_ok());
        assert_eq!(safe_multiply(100.0, 0.15).unwrap(), 15.0);
    }

    #[test]
    fn test_calculate_percentage() {
        assert_eq!(calculate_percentage(1000.0, 15.0).unwrap(), 150.0);
        assert!(calculate_percentage(-100.0, 15.0).is_err());
        assert!(calculate_percentage(1000.0, -5.0).is_err());
        assert!(calculate_percentage(1000.0, 150.0).is_err());
    }

    #[test]
    fn test_validate_region_code() {
        assert!(validate_region_code("110000").is_ok());
        assert!(validate_region_code("310000").is_ok());
        assert!(validate_region_code("").is_err());
        assert!(validate_region_code("1100").is_err());
        assert!(validate_region_code("11000a").is_err());
    }

    #[test]
    fn test_get_province_code() {
        assert_eq!(get_province_code("110101").unwrap(), "110000");
        assert_eq!(get_province_code("310115").unwrap(), "310000");
    }
}
